#!/bin/sh

export E2E_MINOR_SOURCE_POSTGRES_VERSION="${E2E_MINOR_SOURCE_POSTGRES_VERSION:-13.9}"
export E2E_MINOR_TARGET_POSTGRES_VERSION="${E2E_MINOR_TARGET_POSTGRES_VERSION:-13.12}"

e2e_test_install() {
  CLUSTER_NAME="$(get_sgcluster_name dbops-restart)"
  DBOPS_NAME="$(get_sgdbops_name minor-version-upgrade)"

  kubectl create namespace "$CLUSTER_NAMESPACE"

  deploy_curl_pod "$CLUSTER_NAMESPACE"

  wait_pods_running "$CLUSTER_NAMESPACE" 1
}

reset_cluster() {
  remove_cluster_if_exists "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"

  wait_until eval '[ "$(kubectl get pvc -n "$CLUSTER_NAMESPACE" --template "{{ .items | len }}")" = 0 ]'

  create_or_replace_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" 2 \
    --set-string cluster.postgres.version="$E2E_MINOR_SOURCE_POSTGRES_VERSION"

  wait_pods_running "$CLUSTER_NAMESPACE" 3
  wait_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"
  switch_cluster_to_first "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"

  set_restarted_pods

  generate_mock_data "$CLUSTER_NAME"
  check_mock_data_samehost "$CLUSTER_NAME"
  wait_until check_mock_data_replication "$CLUSTER_NAME"

  if kubectl patch sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" --type json \
    --dry-run=server -p "$(cat << EOF
[
  {"op":"replace","path":"/spec/postgres/version","value":"$E2E_MINOR_TARGET_POSTGRES_VERSION"}
]
EOF
        )" >/dev/null 2>&1
  then
    success "Can change SGCluster postgres version directly."
  else
    fail "Can not change SGCluster postgres version directly."
  fi
}

trigger_cluster_require_restart() {
  kubectl patch sgcluster -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" --type merge \
    -p "spec: { pods: { customEnv: { patroni: [{ name: REQUIRE_RESTART, value: '$(date +%s)' }] } } }"
  kubectl wait sgcluster --timeout "${E2E_TIMEOUT}s" -n "$CLUSTER_NAMESPACE" "$CLUSTER_NAME" --for condition=PendingRestart
}

check_restart() {
  local NOT_RESTARTED_PODS="$1"
  local SKIP_CHECK_DATA="$2"

  test -n "$RESTARTED_PODS"

  assert_dbops_running "$DBOPS_NAME" "$CLUSTER_NAMESPACE"

  assert_dbops_completion "$DBOPS_NAME" "$CLUSTER_NAMESPACE" "$((E2E_TIMEOUT * 2))"

  local INITIAL_INSTANCES
  INITIAL_INSTANCES="$(kubectl get sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME" -o json)"
  INITIAL_INSTANCES="$(printf '%s' "$INITIAL_INSTANCES" | jq '.status.restart.initialInstances | length')"
  if printf '%s %s' "$RESTARTED_PODS" "$NOT_RESTARTED_PODS" | wc -w | grep -q "^$INITIAL_INSTANCES$"
  then
    success "Instances after minor version upgrade match the initial instances in status ($INITIAL_INSTANCES)"
  else
    fail "Instances after minor version upgrade ($(printf '%s %s' "$RESTARTED_PODS" "$NOT_RESTARTED_PODS" | wc -w)) do not match the initial instances in status ($INITIAL_INSTANCES)"
  fi

  local DBOPS_CREATION_TIMESTAMP
  DBOPS_CREATION_TIMESTAMP="$(kubectl get sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME" --template='{{ .metadata.creationTimestamp }}')"
  DBOPS_CREATION_TIMESTAMP="$(date -d "$DBOPS_CREATION_TIMESTAMP" +%s)"
  local POD_CREATION_TIMESTAMP
  local POD
  for POD in $RESTARTED_PODS
  do
    POD_CREATION_TIMESTAMP="$(kubectl get pod -n "$CLUSTER_NAMESPACE" "$POD" --template='{{ .metadata.creationTimestamp }}')"
    POD_CREATION_TIMESTAMP="$(date -d "$POD_CREATION_TIMESTAMP" +%s)"
    if [ "$POD_CREATION_TIMESTAMP" -lt "$DBOPS_CREATION_TIMESTAMP" ]
    then
      fail "Pod $POD was not restarted"
    else
      success "Pod $POD was restarted"
    fi
  done
  for POD in $NOT_RESTARTED_PODS
  do
    POD_CREATION_TIMESTAMP="$(kubectl get pod -n "$CLUSTER_NAMESPACE" "$POD" --template='{{ .metadata.creationTimestamp }}')"
    POD_CREATION_TIMESTAMP="$(date -d "$POD_CREATION_TIMESTAMP" +%s)"
    if [ "$POD_CREATION_TIMESTAMP" -lt "$DBOPS_CREATION_TIMESTAMP" ]
    then
      success "Pod $POD was not restarted"
    else
      fail "Pod $POD was restarted"
    fi
  done

  if [ "$(kubectl get -n "$CLUSTER_NAMESPACE" sgcluster "$CLUSTER_NAME" \
    --template '{{ .spec.postgres.version }}')" = "$E2E_MINOR_TARGET_POSTGRES_VERSION" ]
  then
    success "cluster postgres version has been updated."
  else
    fail "cluster postgres version has not been updated."
  fi

  if [ "$SKIP_CHECK_DATA" != true ]
  then
    check_mock_data_samehost "$CLUSTER_NAME"
    if [ "$INITIAL_INSTANCES" -ge 2 ]
    then
      wait_until check_mock_data_replication "$CLUSTER_NAME"
    fi
  fi
}

set_restarted_pods() {
  RESTARTED_PODS="$1"
  NOT_RESTARTED_PODS="$2"
  if [ -z "$RESTARTED_PODS" ]
  then
    RESTARTED_PODS="$(kubectl get pod -n "$CLUSTER_NAMESPACE" -l "app=StackGresCluster,stackgres.io/cluster-name=$CLUSTER_NAME,stackgres.io/cluster=true" \
    --template '{{ range .items }}{{ printf "%s " .metadata.name }}{{ end }}')"
  fi
}
